import {Injectable} from '@nestjs/common';
// ORM
import {InjectRepository} from '@nestjs/typeorm';
import {Repository, UpdateResult} from 'typeorm';
import {ApplyEntity} from '../entity/apply.entity';
import {ApplyDeviceEntity} from '../entity/apply.device.entity';
import {ApplyUserEntity} from '../entity/apply.user.entity';
import {ApplyDto} from '../dto/apply.dto';
import {ApplyStatus} from "../common/constants";

@Injectable()
export class ApplyService {
    constructor(
        @InjectRepository(ApplyEntity)
        private readonly applyRepository: Repository<ApplyEntity>,
    ) {
    }

    async createOne(ApplyDto: ApplyDto): Promise<ApplyEntity> {
        return await this.applyRepository.save(ApplyDto);
    }

    async editOneStatus(id: string, status: ApplyStatus): Promise<UpdateResult> {
        return await this.applyRepository.update({id}, {status});
    }

    // async approve(id: string, status: ApproveStatus | ApplyStatus, manager: EntityManager, nextApproveAccountId?: string): Promise<UpdateResult> {
    //     return await manager.update(ApplyEntity,{id}, {nextApproveAccountId: nextApproveAccountId || '', status});
    // }

    async getOneById(id: string): Promise<ApplyEntity> {
        const qb = this.applyRepository.createQueryBuilder('apply');
        qb.where({id})
        qb.innerJoinAndMapOne('apply.deviceInfo', ApplyDeviceEntity, 'device', 'apply.deviceSn = device.deviceSn')
        qb.innerJoinAndMapOne('apply.applyUserInfo', ApplyUserEntity, 'applyUser', 'apply.applyAccountId = applyUser.accountId')
        return qb.getOne()
    }

    async getApplyDateTimeRangeByDevice(deviceSn: string): Promise<ApplyEntity[]> {
        const qb = this.applyRepository.createQueryBuilder('apply');
        qb.where({deviceSn})
        qb.andWhere("apply.status IN (:...statusArr)", { statusArr: [ ApplyStatus.PENDING, ApplyStatus.PASSED ] })
        return qb.getMany()
    }

    /**
     * 根据申请者账号id和申请状态分页获取申请记录列表
     * 分页查询
     * @param applyAccountId
     * @param pageIndex
     * @param pageSize
     * @param status
     */
    async getPaginationDataByApplyAccountIdAndStatus(pageIndex: number, pageSize: number, applyAccountId: string, status: ApplyStatus): Promise<[ApplyEntity[], number]> {
        const qb = this.applyRepository.createQueryBuilder('apply');
        if (applyAccountId) {
            qb.where({applyAccountId})
        }
        if (status) {
            qb.andWhere({status})
        }
        qb.innerJoinAndMapOne('apply.deviceInfo', ApplyDeviceEntity, 'device', 'apply.deviceSn = device.deviceSn')
        qb.innerJoinAndMapOne('apply.applyUserInfo', ApplyUserEntity, 'applyUser', 'apply.applyAccountId = applyUser.accountId')
        qb.leftJoinAndMapOne('apply.approveUserInfo', ApplyUserEntity, 'approveUser', 'apply.nextApproveAccountId = approveUser.accountId')
        qb.offset((pageIndex - 1) * pageSize).limit(pageSize)
        qb.orderBy({
            'apply.applyTime': 'DESC'
        })
        return qb.getManyAndCount()
    }

    /**
     * 根据申请状态分页获取申请列表
     * 分页查询
     * @param pageIndex
     * @param pageSize
     * @param status
     */
    async getPaginationDataByStatus(pageIndex: number, pageSize: number, status: ApplyStatus): Promise<[ApplyEntity[], number]> {
        const qb = this.applyRepository.createQueryBuilder('apply');
        qb.where({status})
        qb.innerJoinAndMapOne('apply.deviceInfo', ApplyDeviceEntity, 'device', 'apply.deviceSn = device.deviceSn')
        qb.innerJoinAndMapOne('apply.applyUserInfo', ApplyUserEntity, 'applyUser', 'apply.applyAccountId = applyUser.accountId')
        qb.leftJoinAndMapOne('apply.approveUserInfo', ApplyUserEntity, 'approveUser', 'apply.nextApproveAccountId = approveUser.accountId')
        qb.offset((pageIndex - 1) * pageSize).limit(pageSize)
        return qb.getManyAndCount()
    }

    /**
     * 根据审批人账号id获取所有待审批列表
     * @param nextApproveAccountId
     */
    async getAllPendingDataByApproveAccountId(nextApproveAccountId: string): Promise<ApplyEntity[]> {
        const qb = this.applyRepository.createQueryBuilder('apply');
        qb.where({nextApproveAccountId, status: ApplyStatus.PENDING})
        qb.innerJoinAndMapOne('apply.deviceInfo', ApplyDeviceEntity, 'device', 'apply.deviceSn = device.deviceSn')
        qb.innerJoinAndMapOne('apply.applyUserInfo', ApplyUserEntity, 'applyUser', 'apply.applyAccountId = applyUser.accountId')
        qb.leftJoinAndMapOne('apply.approveUserInfo', ApplyUserEntity, 'approveUser', 'apply.nextApproveAccountId = approveUser.accountId')
        qb.orderBy({
            'apply.applyTime': 'DESC'
        })
        return qb.getMany()
    }
}
